﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Text;
using KQReport.Utils;
using Utils.DB.OleDb;
using System.Linq;

namespace KQReport
{
    public class KqDetail
    {
        public KqDetail(User user)
        {
            User = user;
        }

        public User User { get; private set; }

        public string Depart
        {
            get { return User.Depart; }
        }


        public int Id
        {
            get { return User.Id; }
        }

        public string Num
        {
            get { return User.Num; }
        }

        public string Name
        {
            get { return User.Name; }
        }
        public string Sex
        {
            get { return User.Sex; }
        }
        public string Sn
        {
            get { return User.Sn; }
        }
        public string Card
        {
            get { return User.Card; }
        }
        public DateTime? Time1 { get; set; }
        public DateTime? Time2 { get; set; }

        public int Count
        {
            get
            {
                if (Time1 != null && Time2 != null) return 2;
                if (Time1 == null && Time2 == null) return 0;
                return 1;
            }
        }

        public int Index { get; set; }

        public static List<KqDetail> MergeResult(List<User> users, List<CheckIn> checkIns, bool use0, bool use1,
            bool use2)
        {
            var kqDetail = users.ToDictionary(p => p.Id, p => new KqDetail(p));
            foreach (var checkIn in checkIns)
            {
                var detail = kqDetail[checkIn.UserId];
                if (detail.Time1 == null)
                    detail.Time1 = checkIn.Time;
                else if (detail.Time2 == null)
                    detail.Time2 = checkIn.Time;
                //else todo
            }
            var result = kqDetail.Select(p => p.Value).ToList();
            if (!use0)
                result.RemoveAll(p => p.Count == 0);
            if (!use1)
                result.RemoveAll(p => p.Count == 1);
            if (!use2)
                result.RemoveAll(p => p.Count == 2);
            int i = 0;
            foreach (var detail in result)
            {
                i++;
                detail.Index = i;
            }
            return result;
        }
        public static void MergeTable(DataTable table,DateTime start,DateTime end,IEnumerable<CheckIn> checkIns)
        {
            table.Columns.Add("Index", typeof (int));
            table.PrimaryKey = new[] {table.Columns["Id"]};
            var cDate = start.Date;
            while (cDate < end)
            {
                table.Columns.Add(string.Format("a{0}", cDate.ToString("yyyyMMdd")), typeof (string));
                cDate = cDate.AddDays(1);
            }
            foreach (var checkIn in checkIns)
            {
                var row = table.Rows.Find(checkIn.UserId);
                string columnName = string.Format("a{0}", checkIn.Time.ToString("yyyyMMdd"));
                string result;
                switch (Conf.Analyse2TimeFormat.Value)
                {
                    case "HH:mm:ss":
                    case "HH:mm":
                        result = checkIn.Time.ToString(Conf.Analyse2TimeFormat.Value);
                        break;
                    default:
                        result = Conf.Analyse2TimeFormat.Value;
                        break;
                }
                row[columnName] = result;
            }
            int i = 0;
            foreach (DataRow row in table.Rows)
            {
                i++;
                row["Index"] = i;
            }
        }
    }

    public class CheckIn
    {
        public CheckIn(int userId, DateTime time)
        {
            UserId = userId;
            Time = time;
        }
        public CheckIn(IDataReader reader)
        {
            UserId = reader.GetInt32(0);
            Time = reader.GetDateTime(1);
        }


        public int UserId { get; set; }
        public DateTime Time { get; set; }


        private const string Basesql =
            @"SELECT   CHECKINOUT.USERID, MIN(CHECKINOUT.CHECKTIME) AS [Time]
FROM      (((CHECKINOUT INNER JOIN
                USERINFO ON CHECKINOUT.USERID = USERINFO.USERID) INNER JOIN
                DEPARTMENTS ON USERINFO.DEFAULTDEPTID = DEPARTMENTS.DEPTID) INNER JOIN
                DEPARTMENTS DEPARTMENTS_1 ON DEPARTMENTS.SUPDEPTID = DEPARTMENTS_1.DEPTID)
WHERE   (DEPARTMENTS.DEPTID = {0} OR DEPARTMENTS.SUPDEPTID = {0} OR DEPARTMENTS_1.SUPDEPTID = {0})
AND CHECKINOUT.CHECKTIME>@Start AND CHECKINOUT.CHECKTIME<@End  ";

        private const string GroupSql = @"GROUP BY CHECKINOUT.USERID, Format(CHECKINOUT.CHECKTIME, 'yyyy-mm-dd')";
        public static List<CheckIn> GetCheckDics(int departId,string user, DateTime start, DateTime end)
        {
            var sql = string.Format(Basesql, departId);
            if (!string.IsNullOrEmpty(user))
                sql += string.Format(" AND USERINFO.Badgenumber in ({0})", user);
            sql += GroupSql;
            var dics = new List<CheckIn>();
            var paramArray = new[]
            {
                new OleDbParameter("@Start", OleDbType.Date) {Value = start},
                new OleDbParameter("@End", OleDbType.Date) {Value = end}
            };
            var reader = SqlHelperEx.ExecuteReader(sql,paramArray);
            while (reader.Read())
                dics.Add(new CheckIn(reader));
            return dics;
        }
    }
}